home *** CD-ROM | disk | FTP | other *** search
- *==========================================================================*
- * ILog.asm -- Fast integer log and antilog routines *
- * By Talin. (c) 1990 Sylvan Technical Arts. *
- *==========================================================================*
- * Format of lograrithms: *
- * These routines represent logarithms as a 32-bit value, where the *
- * upper 16 bits are the characteristic, and the lower 16 bits are *
- * the mantissa. *
- * Both routines deal with logs to the base 2. These can be converted *
- * other bases by multiplying by the appropriate constant. *
- * *
- * Notes: *
- * None of these routines require any data segment references. *
- *==========================================================================*
-
- xdef _IntLg
- xdef IntLg
- xdef _IntAlg
- xdef IntAlg
-
- *==========================================================================*
- * IntLg *
- * Inputs: d0 = 32-bit integer value *
- * Outputs: d0 = logarithm in standard format *
- * Scratch: d1,d2,a0 *
- * Max Error: 1 part in 100,000 *
- *==========================================================================*
-
- _IntLg:
- move.l 4(sp),d0
- IntLg:
- tst.l d0 ; test number to see if it's zero
- beq.s 9$ ; if number is zero, log is impossible...
-
- moveq #32,d1 ; d1 <-- characteristic (init 32)
-
- cmp.l #$10000,d0 ; if top 16 bits empty
- bhs.s 1$ ; then
- swap d0 ; shift over 16 bits
- clr.w d0 ; clear lower bits...
- moveq #16,d1 ; and subtract 16 from characteristic.
-
- 1$ cmp.l #$1000000,d0 ; if top 8 bits empty
- bhs.s 2$ ; then
- lsl.l #8,d0 ; shift over 8 bits
- subq.l #8,d1 ; subtract 8 from characteristic
-
- 2$ subq #1,d1 ; subtract 1 from characteristic.
- add.l d0,d0 ; shift over by 1
- bcc.s 2$ ; do until carry is set.
-
- ; at this point, the carry is set with the topmost bit.
- ; the next 8 bits are in the lookup, and any bits leftover will be used for the
- ; interpolation.
-
- lsr.l #8,d0 ; d0 <-- 00aabbbb
- move.w d0,-(sp) ; save interpolation bits...
- swap d0 ; d0 <-- bbbb00aa
- add.w d0,d0 ; d0 = lookup value
- lea logtable2,a0 ; address of log table
- add.w d0,a0 ; add offset to table address
- move.w (a0)+,d0 ; get the log value
- move.w (a0),d2 ; get the next log value after that
- sub.w d0,d2 ; get difference between table entries.
- mulu.w (sp)+,d2 ; times the interpolation bits
- swap d2 ; get high word
- add.w d2,d0 ; add to log value
- ; bcs here???
- swap d0 ; prepare to insert characteristic
- move.w d1,d0 ; insert it
- swap d0 ; return.
-
- rts ; return a long: cccc.mmmm
-
- 9$ moveq #-1,d0
- rts
-
- logtable2:
- dc.w 00000,00369,00736,01102,01466,01829,02190,02551
- dc.w 02909,03267,03623,03978,04331,04683,05034,05384
- dc.w 05732,06079,06425,06769,07112,07454,07795,08134
- dc.w 08473,08810,09146,09480,09814,10146,10477,10807
- dc.w 11136,11464,11791,12116,12440,12764,13086,13407
- dc.w 13727,14046,14363,14680,14996,15311,15624,15937
- dc.w 16248,16559,16868,17177,17484,17791,18096,18401
- dc.w 18704,19007,19308,19609,19909,20207,20505,20802
- dc.w 21098,21393,21687,21980,22272,22564,22854,23144
- dc.w 23433,23720,24007,24293,24579,24863,25146,25429
- dc.w 25711,25992,26272,26551,26830,27108,27384,27660
- dc.w 27936,28210,28484,28757,29029,29300,29571,29840
- dc.w 30109,30378,30645,30912,31178,31443,31707,31971
- dc.w 32234,32496,32758,33019,33279,33538,33797,34055
- dc.w 34312,34569,34825,35080,35334,35588,35841,36094
- dc.w 36346,36597,36847,37097,37346,37595,37842,38090
- dc.w 38336,38582,38827,39072,39316,39559,39802,40044
- dc.w 40286,40527,40767,41006,41246,41484,41722,41959
- dc.w 42196,42432,42667,42902,43137,43370,43603,43836
- dc.w 44068,44300,44530,44761,44991,45220,45448,45676
- dc.w 45904,46131,46357,46583,46809,47034,47258,47482
- dc.w 47705,47928,48150,48372,48593,48813,49034,49253
- dc.w 49472,49691,49909,50127,50344,50560,50776,50992
- dc.w 51207,51422,51636,51850,52063,52276,52488,52700
- dc.w 52911,53122,53332,53542,53751,53960,54169,54377
- dc.w 54584,54791,54998,55204,55410,55615,55820,56025
- dc.w 56229,56432,56635,56838,57040,57242,57443,57644
- dc.w 57845,58045,58245,58444,58643,58841,59039,59237
- dc.w 59434,59631,59827,60023,60219,60414,60609,60803
- dc.w 60997,61190,61384,61576,61769,61961,62152,62343
- dc.w 62534,62725,62915,63104,63294,63483,63671,63859
- dc.w 64047,64234,64421,64608,64794,64980,65166,65351
- dc.w 00000
-
- *==========================================================================*
- * IntAlg
- * Inputs: d0 = logarithm in standard format
- * Outputs: d0 = 32-bit integer value
- * Scratch: d1,d2,a0
- * Max Error: 1 part in 30,000
- *==========================================================================*
-
- _IntAlg:
- move.l 4(sp),d0
- IntAlg:
- move.w d0,d1 ; get mantissa
-
- lsr.w #8,d1 ; get the "lookup" part.
- add.w d1,d1 ; times 2 for table
-
- lea alogtable,a0 ; address of antilog table
- add.w d1,a0 ; plus offset
-
- move.w (a0)+,d1 ; get the digits to use.
- move.w (a0),d2 ; get the next value too
- sub.w d1,d2 ; distance between table entries
-
- ; now we need to interpolate.
- lsl.w #8,d0 ; adjust interpolation bits
- add.w #128,d0 ; add rounding factor??
- mulu.w d0,d2 ; times interpolation factor
- swap d2 ; get high word
- add.w d2,d1 ; and adjust result.
-
- ; now we have 16 bits in the lower half of d1, and the upper half of d1 is how
- ; many to shift them over...
-
- swap d1 ; put it in the top
- bset #0,d1 ; make the lowest bit a 1
- ror.l #1,d1 ; make the leading bit a 1, shift others over
-
- swap d0 ; get bits to shift.
- cmp.w #32,d0 ; if d0 > 33
- bhs.s 9$ ; then fail, we can't alog this.
- eor.b #31,d0 ; reverse direction of shift
-
- lsr.l d0,d1 ; rotate number
- moveq #0,d0 ; clear d0
- addx.l d0,d1 ; round using carry bit
- move.l d1,d0 ; put in d0
- rts ; return
-
- 9$ moveq #0,d0 ; return 0 (value that can neve be logged)
- rts ; return
-
- alogtable:
- dc.w 00000,00178,00356,00535,00714,00893,01073,01254
- dc.w 01435,01617,01799,01981,02164,02348,02532,02716
- dc.w 02902,03087,03273,03460,03647,03834,04022,04211
- dc.w 04400,04590,04780,04971,05162,05353,05546,05738
- dc.w 05932,06125,06320,06514,06710,06906,07102,07299
- dc.w 07496,07694,07893,08092,08292,08492,08693,08894
- dc.w 09096,09298,09501,09704,09908,10113,10318,10524
- dc.w 10730,10937,11144,11352,11560,11769,11979,12189
- dc.w 12400,12611,12823,13036,13249,13462,13676,13891
- dc.w 14106,14322,14539,14756,14974,15192,15411,15630
- dc.w 15850,16071,16292,16514,16737,16960,17183,17408
- dc.w 17633,17858,18084,18311,18538,18766,18995,19224
- dc.w 19454,19684,19915,20147,20379,20612,20846,21080
- dc.w 21315,21550,21786,22023,22260,22498,22737,22977
- dc.w 23216,23457,23698,23940,24183,24426,24670,24915
- dc.w 25160,25406,25652,25900,26148,26396,26645,26895
- dc.w 27146,27397,27649,27902,28155,28409,28664,28919
- dc.w 29175,29432,29690,29948,30207,30466,30727,30988
- dc.w 31249,31512,31775,32039,32303,32568,32834,33101
- dc.w 33369,33637,33906,34175,34446,34717,34988,35261
- dc.w 35534,35808,36083,36359,36635,36912,37190,37468
- dc.w 37747,38028,38308,38590,38872,39155,39439,39724
- dc.w 40009,40295,40582,40870,41158,41448,41738,42029
- dc.w 42320,42613,42906,43200,43495,43790,44087,44384
- dc.w 44682,44981,45280,45581,45882,46184,46487,46791
- dc.w 47095,47401,47707,48014,48322,48631,48940,49251
- dc.w 49562,49874,50187,50500,50815,51131,51447,51764
- dc.w 52082,52401,52721,53041,53363,53685,54008,54333
- dc.w 54658,54983,55310,55638,55966,56296,56626,56957
- dc.w 57289,57622,57956,58291,58627,58964,59301,59640
- dc.w 59979,60319,60661,61003,61346,61690,62035,62381
- dc.w 62727,63075,63424,63774,64124,64476,64828,65182
- dc.w 00000
-
- end
-